package cn.edu.tju.elm.controller;

import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.SecurityUtils;
import cn.edu.tju.core.security.rest.dto.LoginDto;
import cn.edu.tju.core.security.rest.dto.UserRegisterDto;
import cn.edu.tju.core.security.rest.dto.UserUpdateDto;
import cn.edu.tju.core.security.rest.dto.AvatarDto;
import cn.edu.tju.core.security.rest.dto.PasswordChangeDto;
import cn.edu.tju.core.security.rest.dto.LoginResponse;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.elm.model.Business;
import cn.edu.tju.elm.service.BusinessService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@RestController
@RequestMapping("/api/users")
@Tag(name = "用户管理", description = "用户账号相关接口")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private BusinessService businessService;

    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "用户注册新账号")
    public HttpResult<User> register(@RequestBody UserRegisterDto registerDto) {
        try {
            // 检查用户名是否已存在
            Optional<User> existingUser = userService.getUserByUsername(registerDto.getUsername());
            if (existingUser.isPresent()) {
                return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "用户名已存在");
            }

            // 创建新用户
            Authority authority = new Authority();
            authority.setName("USER");
            User newUser = User.builder()
                    .username(registerDto.getUsername())
                    .password(SecurityUtils.BCryptPasswordEncode(registerDto.getPassword()))
                    .userSex(registerDto.getUserSex())
                    .userImg(registerDto.getUserImg())
                    .activated(true)
                    .authorities(java.util.Set.of(authority))
                    .build();

            User savedUser = userService.createUser(newUser);
            // 清除密码信息
            savedUser.setPassword(null);
            return HttpResult.success(savedUser);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "注册失败: " + e.getMessage());
        }
    }

    @PostMapping("/registerB")
    @Operation(summary = "用户注册", description = "用户注册新账号")
    public HttpResult<User> registerB(@RequestBody UserRegisterDto registerDto) {
        try {
            // 检查用户名是否已存在
            Optional<User> existingUser = userService.getUserByUsername(registerDto.getUsername());
            if (existingUser.isPresent()) {
                return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "用户名已存在");
            }

            // 创建新用户
            Authority authority = new Authority();
            authority.setName("BUSINESS");
            User newUser = User.builder()
                    .username(registerDto.getUsername())
                    .password(SecurityUtils.BCryptPasswordEncode(registerDto.getPassword()))
                    .userSex(registerDto.getUserSex())
                    .userImg(registerDto.getUserImg())
                    .activated(true)
                    .authorities(java.util.Set.of(authority))
                    .build();

            User savedUser = userService.createUser(newUser);

            // 创建关联的 Business
            Business business = new Business();
            business.setBusinessName(registerDto.getBusinessName()); // 从 DTO 获取商家名
            business.setBusinessOwner(savedUser);
            businessService.saveBusiness(business);

            // 清除密码信息
            savedUser.setPassword(null);
            return HttpResult.success(savedUser);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "注册失败: " + e.getMessage());
        }
    }


    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户登录验证")
    public HttpResult<LoginResponse> login(@RequestBody LoginDto loginDto) {
        try {
            Optional<User> userOpt = userService.getUserByUsername(loginDto.getUsername());
            if (userOpt.isPresent()) {
                User user = userOpt.get();
                // 验证密码
                if (SecurityUtils.checkPassword(loginDto.getPassword(), user.getPassword())) {
                    // 生成JWT token
                    String token = SecurityUtils.generateToken(user.getUsername());
                    
                    // 检查是否为商家用户，如果是则获取店铺ID
                    Long businessId = null;
                    boolean isBusiness = user.getAuthorities().stream()
                            .anyMatch(authority -> "BUSINESS".equals(authority.getName()));
                    if (isBusiness) {
                        Business business = businessService.getBusinessByUserId(user.getId());
                        if (business != null) {
                            businessId = business.getId();
                        }
                    }
                    
                    LoginResponse response = new LoginResponse(
                            token,
                            user.getUsername(),
                            user.getId(),
                            user.getUserImg(),
                            user.getUserSex(),
                            user.getAuthorities(),
                            businessId
                    );
                    return HttpResult.success(response);
                } else {
                    return HttpResult.failure(ResultCodeEnum.UNAUTHORIZED, "密码错误");
                }
            } else {
                return HttpResult.failure(ResultCodeEnum.UNAUTHORIZED, "用户不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "登录失败: " + e.getMessage());
        }
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取用户信息", description = "根据ID获取用户详细信息")
    public HttpResult<User> getUserById(@PathVariable Long id) {
        try {
            Optional<User> userOpt = userService.getUserById(id);
            if (userOpt.isPresent()) {
                User user = userOpt.get();
                // 清除密码信息
                user.setPassword(null);
                return HttpResult.success(user);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "用户不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取用户信息失败: " + e.getMessage());
        }
    }

    @GetMapping("/profile")
    @Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息")
    public HttpResult<User> getCurrentUser(@RequestParam User user) {
        try {
                user.setPassword(null);
                return HttpResult.success(user);

        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取用户信息失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新用户信息", description = "更新用户基本信息")
    public HttpResult<User> updateUser(@PathVariable Long id, @RequestBody UserUpdateDto updateDto) {
        try {
            Optional<User> userOpt = userService.getUserById(id);
            if (userOpt.isPresent()) {
                User user = userOpt.get();
                
                // 更新用户信息
                if (updateDto.getUsername() != null) {
                    user.setUsername(updateDto.getUsername());
                }
                if (updateDto.getUserSex() != null) {
                    user.setUserSex(updateDto.getUserSex());
                }
                if (updateDto.getUserImg() != null) {
                    user.setUserImg(updateDto.getUserImg());
                }

                User updatedUser = userService.updateUserInfo(user);
                // 清除密码信息
                updatedUser.setPassword(null);
                return HttpResult.success(updatedUser);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "用户不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "更新用户信息失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/avatar")
    @Operation(summary = "更新用户头像", description = "更新用户头像（base64格式）")
    public HttpResult<String> updateAvatar(@PathVariable Long id, @RequestBody AvatarDto avatarDto) {
        try {
            boolean success = userService.updateAvatar(id, avatarDto.getBase64());
            if (success) {
                return HttpResult.success("头像更新成功");
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "用户不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "更新头像失败: " + e.getMessage());
        }
    }

    @PostMapping("/{id}/password")
    @Operation(summary = "修改密码", description = "用户修改密码（需要验证旧密码）")
    public HttpResult<String> changePassword(@PathVariable Long id, @RequestBody PasswordChangeDto passwordDto) {
        try {
            boolean success = userService.changePassword(id, passwordDto.getOldPassword(), 
                    SecurityUtils.BCryptPasswordEncode(passwordDto.getNewPassword()));
            if (success) {
                return HttpResult.success("密码修改成功");
            } else {
                return HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "密码修改失败");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "密码修改失败: " + e.getMessage());
        }
    }
}
